<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>

        class legacySandbox {
            constructor() {
                this.modifyPropsMap = new Map();
                this.addedPropsMap = new Map();
                this.currrentPropsMap = new Map();
                const fackWindow = Object.create(null);
                const proxy = new Proxy(fackWindow, {
                    get: (target, prop) => {
                        return window[prop]
                    },
                    set: (target, prop, value) => {
                        if (!window.hasOwnProperty(prop)) {
                            this.addedPropsMap.set(prop, value);
                        } else if (!this.modifyPropsMap.has(prop)) {
                            // 保存修改的原值
                            this.modifyPropsMap.set(prop, window[prop]);

                        }
                        this.currrentPropsMap.set(prop, value);
                        window[prop] = value;

                    }
                });
                this.proxy = proxy;

            }

            setWindowProp(key, value) {
                // 设置window属性
                if (value === undefined) {
                    // 如果值为undefined，删除属性
                    delete window[key];
                } else {
                    // 否则设置属性
                    window[key] = value;
                }
            }
            // 失活沙箱
            inactive() {
                this.modifyPropsMap.forEach((value, key) => {
                    setWindowProp(key, value);
                });
                this.addedPropsMap.forEach((value, key) => {
                    setWindowProp(key, undefined);
                });

            }

            active() {
                this.currrentPropsMap.forEach((value, key) => {
                    // 恢复当前属性
                    this.setWindowProp(key, value);
                });
            }
        }

        let sandbox = new legacySandbox();
        sandbox.active();
        sandbox.proxy.a = 1;
        sandbox.proxy.b = 2;
        sandbox.inactive();
        console.log(window.a); // undefined


        // 1/无论是快照还是这种代理 都只能在应用单例的时候使用 如果同时加载两个应用就会混乱
        // 2.子应用调用的是window 并不是 sandbox.proxy ,通过下面的方式调用子应用就没问题了

        (function (window) {
            
            // 这里的window.a = 1 会被沙箱代理
            window.a = 1;
            console.log(window.a); // 1
        })(sandbox.proxy);

    </script>
</body>

</html>